"""
闭包的形成条件：
外部函数返回的是内部函数的引用
内部函数可以反问并操作外部函数的局部变量
"""


def outer(out_num):
    def inner(in_num):
        print('out', out_num)
        print('in', in_num)
        print("他们的和是", out_num + in_num)

    return inner


# f 持有了inner函数的引用
f = outer(10)

"""
闭包中的外部局部变量存储在__closure__中
"""
closure = f.__closure__
print(closure)
for i in closure:
    print(i.cell_contents)
# f(5)
# f(15)



"""案例1 幂运算"""


def power(exponent):
    """进行幂运算"""

    def calculate_power(base):
        return base ** exponent

    return calculate_power


square = power(2)
# print(square(4))


"""
案例二 计算每天的平均开销
"""
def avg():
    # 使用闭包来保证num_list的安全性
    num_list = []
    def inner(num):
        num_list.append(num)
        print(sum(num_list) / len(num_list))
    return inner

avg1 = avg()
# avg1(100)
# avg1(200)
# avg1(300)

"""
案例三 购物车
"""
def shopping_cart():
    # 购物车的清单列表
    items = []
    def add_item(item):
        items.append(item)
        print(f"已添加到购物车:{item}")

    def get_items():
        return items
    return add_item,get_items

# usr_cart,usr_get = shopping_cart()
# usr_cart("手机")
# usr_cart("耳机")
# usr_cart("相机")
# print(usr_get())